perm filename SERVO.OLD[CMS,LCS]3 blob
sn#426287 filedate 1979-03-20 generic text, type T, neo UTF8
00100 TITLE SERVO
00200 .INSERT ASMBL.FAI[CMS,LCS]
00300
00500 ;I/O address definitions.
00600 DAC ← 100000 ;8 bit DAC.
00700 JCR ← 120000 ;Joint control output register.
00800 ENCL ← 140000 ;Encoder mux low.
00900 ENCH ← 140001 ;Encoder mux high.
01000
01100 STKSIZ ← 377 ;Stack size.
01200 LSBENB ← 40 ;Enable LSB servo.
01300
01400 ;Zero page variables.
01500 ;Not shared.
01600
01800 DSPAT: BLOCK 2 ;Dispatch address for commands.
01900 DEFCMD: 0 ;Deferred command.
02000 SAVPOS: BLOCK 2 ;Position for deferred servo command.
02100
02200 CMDVEL: BLOCK 2 ;Commanded velocity.
02300 CURVEL: BLOCK 2 ;Current velocity.
02400 0 ;SETPT-1.
02500 SETPT: BLOCK 2 ;Current setpoint.
02600 0 ;SETINC-1.
02700 SETINC: BLOCK 2 ;Interpolating increment for setpoints.
02800 OLDSP: BLOCK 2 ;Last commanded setpoint, for CMDVEL.
02900 POSERR: BLOCK 2 ;Current position error.
03000 DACSIG: BLOCK 2 ;Scratch.
03100
03200 INCTR: 0 ;Count the interpolations.
03300 HSTTMR: 0 ;Count ticks between host commands.
03400
03500 LOGTMP: BLOCK 4 ;Temp for the arithmetic routines.
03600
03700 ZAPEND ← .-1 ;Clear all the above in startup.
03800
03900 CURPOS: BLOCK 2 ;Current position, extended to 2 bytes.
04000
04100 TL: 0 ;Scratch for grey to binary.
04200 TH: 0
04300
04400 FTMP: BLOCK 2 ;Copy of friction coefficient for multiply.
00100 ;Shared ram.
00200 LOC 200 ;Second half of zero page.
00300
00400 0 ;Locked.
00500 STATUS: 0 ;Flags for the host.
00600
00700 0 ;Locked.
00800 MODE: 0 ;Mode bits from host.
00900
01000 CKWORD: BLOCK 2 ;Host I/O check/command word.
01100 CMDPOS: BLOCK 2 ;Commanded position from host.
01200
01225 0 ;Locked.
01250 IOCTRL: 0 ;Copy of JCR output port.
01275
01300 ;NINTER = function of INTSCL?
01400 0 ;Locked.
01500 NINTER: 0 ;# of interpolations between position
01600 ;commands.
01700 0 ;Locked.
01800 INTSCL: 0 ;# of bits to shift setpoint dif for
01900 ;interpolating.
02000 0 ;Locked.
02100 HSTLIM: 0 ;# of clock ticks allowed between host
02200 ;commands.
02300 FRICTN: BLOCK 2 ;Viscous damping coefficient.
02400 GRAVTY: BLOCK 2 ;DC offset for gravity.
02500 POSTOL: BLOCK 2 ;Half-width of position tolerance band.
02600 INTTOL: BLOCK 2 ;Half-width of integration band.
02700
02800
02900 ;Start of prom.
03000 LOC 174000
03100
03200 INITBL: STATUS ↔ 200
03300 MODE ↔ 0
03400
03500 NINTER ↔ =32
03600 INTSCL ↔ 5
03700
03800 HSTLIM ↔ =48
03900
04000 377 ;End of INITBL flag.
00100 ;Power on and restart reset.
00200 START: CLD
00300 LDXI STKSIZ ;Setup stack.
00400 TXS
00500
00600 LDAI 0
00700 LDXI ZAPEND
00800 RLOOP: STAZX 0 ;Reset ram.
00900 DEX
01000 BPL RLOOP
01100 STA DAC ;Clear DAC.
01200
01300 LDXI 370 ;-8.
01400 ZSR: STAZX FRICTN+10 ;Clear shared ram.
01500 INX
01600 BMI ZSR
01700
01800 TAY
01900 BEQ RSTDEF ;Jump
02000
02100
02200 DLOOP: INY
02300 LDAY INITBL ;Init ram.
02400 STAZX 0
02500 INY
02600
02700 RSTDEF: LDXY INITBL
02800 CPXI 377
02900 BNE DLOOP
03000
03100 STOP: SEI ;Disable interrupts and stop?
03200 JSR GETPOS ;Read encoder and convert to binary.
03400
03500 JSR SETPOS ;Set position and stop.
03600
03700 CLI ;End of reset.
00100 RSTCKW: LDAI 0 ;Reset check word.
00200 SEI
00300 STAZ CKWORD
00400 STAZ CKWORD+1
00500 CLI
00600 ;Idle loop. Wait for command.
00700 IDLE: LDAZ CKWORD+1;Check for new check word.
00800 BEQ IDLE ;Not equal if bit 7 is 2's comp. of low byte?
00900
01000 CLC
01100 SEI
01200 ADCZ CKWORD
01300 LDXZ CKWORD+1
01400 CLI
01500 TAY
01600 BNE STOP ;Check word error.
01700 ;Check here for immediate or deferred.
01800 LDAZ DEFCMD ;Check if no TICK?
01900 BNE STOP
02000
02100 SEI
02200 LDAZ CMDPOS ;Read position for servo command.
02300 LDYZ CMDPOS+1
02400 CLI
02500
02600 STAZ SAVPOS ;Save it for later.
02700 STYZ SAVPOS+1
02800
02900 STXZ DEFCMD ;Save deferred command.
03000
03100 BNE RSTCKW ;Done. Jump and handshake with CKWORD.
03200
03300 ;If HSTTMR or CKWORD or ? then stop?
03400 ;Check notebook and add stop? etc.
03600 ;Check GPOSER and in servo formula for sign reverse?
00100 ;Deferred commands.
00150 ;Put this routine on page 10-2.
00200 CMDSRV: LDAZ MODE ;Servo command.
00300 ANDI 202 ;Test for servo enabled.
00400 CMPI 200
00500 BEQ ENBLD
00600 JMP CMDEND ;No. End this command.
00700
00800 ENBLD: LDAZ SAVPOS ;Enabled.
00900 LDXZ SAVPOS+1;Get position.
01000 STAZ DACSIG
01100 STXZ DACSIG+1
01200 SEC
01300 SBCZ SETPT
01400 STAZ SETINC
01500 TXA
01600 SBCZ SETPT+1
01700 LDXI 0
01800 STXZ SETPT-1
01900 STXZ SETINC-1
02000 LDXZ INTSCL
02100
02200 SCAL: CMPI 200 ;Extend sign.
02300 RORA
02400 RORZ SETINC
02500 RORZ SETINC-1
02600 DEX
02700 BNE SCAL
02800
02900 STAZ SETINC+1
03000 LDAZ NINTER
03100 STAZ INCTR
03200 SEC
03300 LDAZ DACSIG
03400 SBCZ OLDSP
03500 STAZ CMDVEL
03600 LDAZ DACSIG+1
03700 SBCZ OLDSP+1
03800 STAZ CMDVEL+1
03900 LDAZ DACSIG
04000 STAZ OLDSP
04100 LDAZ DACSIG+1
04200 STAZ OLDSP+1
04300
04400 LDAZ IOCTRL
04500 ORAI 44 ;Turn on servo and current mode enable bits.
04600 STAZ IOCTRL
04700 STA JCR ;Output it.
04800 LDAZ HSTLIM ;Reset host timer.
04900 STAZ HSTTMR
05000 JMP CMDEND
00100 ;Clock tick interrupt.
00200 TICK: PHA ;Save state.
00300 TXA
00400 PHA
00500 TYA
00600 PHA
00700
00750 JSR GETPOS ;Read position and convert to binary.
00770
00790 ;Position conversion routine.
00795 ;Put this routine on page 10-3.
00800 GETPOS: LDY ENCL ;Read encoder.
00900 LDA ENCH
01000
01100 ;Convert from grey to binary.
01200 STAZ TH
01300 LSRA ;Shift by 1.
01400 EORZ TH
01500 STAZ TH
01600 TAX ;X ← high byte.
01700
01800 TYA
01900 STAZ TL
02000 RORA
02100 EORZ TL
02200 STAZ TL
02300
02400 LSRZ TH ;Shift by 2.
02500 RORA
02600 LSRZ TH
02700 RORA
02800
02900 EORZ TL
03000 STAZ TL
03100 TAY ;Y ← low byte.
03200 TXA
03300 EORZ TH
03400 STAZ TH
03500
03600 LSRA ;Shift by 4.
03700 RORZ TL
03800 LSRA
03900 RORZ TL
04000 LSRA
04100 RORZ TL
04200 LSRA
04300 RORZ TL
04400
04500 EORZ TH
04600 STAZ TH
04700 TYA
04800 EORZ TL
04900 EORZ TH ;Shift by 8.
05000 ;Returns converted position in A (low) and TH (high).
05100 RTS
00100 TAY ;Save low byte of binary position.
00200 LDXZ TH ;Get high byte.
00300 SEC
00400 SBCZ CURPOS ;Subtract the old position
00500 STAZ CURVEL ;yielding the velocity.
00600 TXA ;High byte of binary position.
00700 SBCZ CURPOS+1
00800 STAZ CURVEL
00900
01000 STYZ CURPOS ;Set the current position.
01100 STXZ CURPOS+1
01200
01300 DECZ HSTTMR ;Count the ticks since the last command
01400 BPL HOSTOK ;and check for timeout.
01500
01600 LDAI 0 ;Host dead. Stop.
01700 STAZ HSTTMR
01800 STAZ CMDVEL
01900 STAZ CMDVEL+1
02000
02100 HOSTOK: LDAI 4
02200 BITZ IOCTRL ;If position mode is off,
02300 BNE INTRS
02400 JMP CURSRV ;don't servo.
02500
02600 ;Interpolate the setpoints.
02700 INTRS: CLC
02800 LDAZ SETPT-1
02900 ADCZ SETINC-1;Add the increment to the setpoint.
03000 STAZ SETPT-1
03100 LDAZ SETPT
03200 ADCZ SETINC
03300 STAZ SETPT
03400 LDAZ SETPT+1
03500 ADCZ SETINC+1
03600 STAZ SETPT+1
03700
03800 DECZ INCTR ;Check if this is the last interpolation.
03900 BNE GPOSER
04000
04100 LDAI 0 ;Clear SETINC if done interpolating.
04200 STAZ SETINC-1
04300 STAZ SETINC
04400 STAZ SETINC+1
04500
04600 ;Calculate the position error.
04700 GPOSER: SEC
04800 LDAZ CURPOS ;POSERR ← CURPOS - SETPT.
04900 SBCZ SETPT
05000 STAZ POSERR
05100 LDAZ CURPOS+1
05200 SBCZ SETPT+1
05300 STAZ POSERR+1
00100 BITZ MODE ;If servo is disabled, we're
00200 BPL OOTOL ;automatically out of tolerance
00300
00400 LDAZ POSERR+1;Test the sign of pos error.
00500 BMI NEGPER
00600
00700 SEI
00800 LDAZ POSTOL ;Positive. Compare with tol.
00900 CMPZ POSERR
01000 LDAZ POSTOL+1
01100 CLI
01200 SBCZ POSERR+1
01300 BCS TOLOK ;In tolerance.
01400 BCC OOTOL ;Jump.
01500
01600 NEGPER: CLC ;Negative. Add the tolerance.
01700 SEI
01800 LDAZ POSTOL
01900 ADCZ POSERR
02000 LDAZ POSTOL+1
02100 CLI
02200 ADCZ POSERR+1
02300 BCS TOLOK ;In tolerance.
02400
02500 OOTOL: LDAZ IOCTRL ;Out of tolerance.
02600 ANDI 177 ;Turn off the in tolerance
02700 BNE WCNTRL ;indicator.
02800
02900 TOLOK: LDAZ IOCTRL ;In tolerance. Turn it on.
03000 ORAI 200
03100 WCNTRL: STAZ IOCTRL
03200 STA JCR ;Copy it to output.
03300
03350 ;Delete from here to end of page if no integrator?
03400 BITZ MODE ;If intergration is disabled,
03500 BVC OOBAND ;turn it off.
03600 LDAZ POSERR+1;Test sign of position error.
03700 BMI ADTOL
03800
03900 SEI
04000 LDAZ INTTOL ;Positive. Compare with tol.
04100 CMPZ POSERR
04200 LDAZ INTTOL+1
04300 CLI
04400 SBCZ POSERR+1
04500 BCS INBAND ;In band. Turn on integrator.
04600 BCC OOBAND ;Jump.
04700
04800 ADTOL: CLC ;Negative. Add the tolerance.
04900 SEI
05000 LDAZ INTTOL
05100 ADCZ POSERR
05200 LDAZ INTTOL+1
05300 CLI
05400 ADCZ POSERR+1
05500 BCS INBAND ;Check if in band.
05600
05700 OOBAND: LDAZ IOCTRL ;Out of band. Turn off
05800 ORAI 10 ;integration by setting the
05900 ANDI 357 ;control bit. LSB servo off.
06000 BNE WCTRL2 ;Jump.
00050 ;Delete from here to WCTRL2 if no LSB servo?
00100 INBAND: LDAI LSBENB ;In band. Is LSB servo enabled?
00200 BITZ MODE
00300 BEQ RCNTRL
00400
00500 LDAZ POSERR ;Yes. Is the error exactly 0?
00600 ORAZ POSERR+1
00700 BNE RCNTRL
00800
00900 LDAZ IOCTRL ;It is. Integration off, LSB
01000 ORAI 30 ;servo on.
01100 BNE WCTRL2 ;Jump.
01200
01300 RCNTRL: LDAZ IOCTRL ;LSB disabled or error
01400 ANDI 347 ;not zero. LSB servo off,
01500 ;integration on.
01600
01700 WCTRL2: STAZ IOCTRL
01800 STA JCR ;Output it.
01900
02000 LDYZ CURVEL ;Get the velocity,
02100 LDAZ CURVEL+1
02200 JSR LOG
02300
02400 SEI
02500 LDXZ FRICTN ;(Copy friction for multiply.)
02600 STXZ FTMP
02700 LDXZ FRICTN+1
02800 CLI
02900 STXZ FTMP+1
03000 LDXI FTMP ;multiply by the friction
03100 JSR MULTIP ;coefficient,
03200 JSR EXP
03300
03400 TAX ;Save high byte.
03500 TYA ;Get low byte.
03600 CLC ;add the position error...
03700 ADCZ POSERR
03800 STAZ DACSIG
03900 TXA
04000 ADCZ POSERR+1
04100 STAZ DACSIG+1
04600
04700 CLC ;...and the gravity offset.
04800 LDAZ DACSIG
04900 SEI
05000 ADCZ GRAVTY
05100 TAY ;Save low byte.
05200 LDAZ GRAVTY+1
05300 CLI
05400 ADCZ DACSIG+1
05600
05700 JSR PUTDAC ;Put result out to the DAC.
00100 CMDSP: LDAZ DEFCMD ;Check for a command.
00200 BEQ INTXIT
00300
00400 ANDI 2 ;Low nibble command bit.
00500 TAX
00600 LDAX CMDTBL ;Get command address.
00700 STAZ DSPAT
00800 LDAX CMDTBL+1
00900 STAZ DSPAT+1
01000
01100 JMPIN DSPAT ;Execute command.
01200
01300 CMDEND: LDAI 0 ;Done with deferred command.
01400 STAZ DEFCMD ;Reset command word.
01500
01600 INTXIT: PLA ;Restore state and dismiss interrupt.
01700 TAY
01800 PLA
01900 TAX
02000 PLA
02100 RTI
02200
02300 CURSRV: LDAI 0 ;Not servoing ("Current mode")...
02400 STAZ SETPT-1 ;Make the setpoint track
02500 LDAZ CURPOS ;the current position in order to
02600 STAZ SETPT ;keep the arm from twitching when
02700 LDAZ CURPOS+1;the host enables the servo.
02800 STAZ SETPT+1
02900 JMP CMDSP ;Go check on commands.
03000
03100 CMDTBL: ;DEFERRED COMMAND TABLE.
03200 CMDEND∧377 ;Nop.
03300 (CMDEND⊗-10)∧377
03400
03500 CMDSRV∧377 ;Servo command.
03600 (CMDSRV⊗-10)∧377
00050 ;Not a subroutine? Put this routine on page 3-1?
00100 ;Set position subroutine.
00200 ;Enter with position in A (low) and X (high).
00300 ;Sets current position to that value, puts the setpoint
00400 ;to the same, clears the setpoint interpolating
00500 ;increment, and goes into stop mode?
00600 SETPOS: STAZ CURPOS ;Set the current position.
00700 STXZ CURPOS+1
00800
00900 STAZ SETPT ;Set the position command.
01000 STXZ SETPT+1
01100 STAZ OLDSP
01200 STXZ OLDSP+1
01300
01400 LDAI 75 ;I/O control bits for servo
01500 STAZ IOCTRL ;enable on, all others off.
01600 STA JCR
01700
01800 LDAI 0
01900 STAZ SETPT-1 ;Clear the setpoint extension,
02000 STAZ SETINC-1;the interpolator,
02100 STAZ SETINC
02200 STAZ SETINC+1
02300 STAZ CMDVEL ;and the commanded velocity.
02400 STAZ CMDVEL+1
02500
02600 LDAZ SETPT ;Return the regs. unchanged.
02700 RTS
02800
02900 ;DAC output subroutine.
03000 ;Enter with 2 byte value in Y (low), A (high).
03100 ;Clobbers all registers, but the 8 bits the
03200 ;DAC got are returned in A.
03300 PUTDAC: BMI NEGDAC ;Assuming the last inst. loaded A.
03400 CPYI 200 ;Positive. Compare with 2↑7.
03700 SBCI 0
03800 BCC INRNGE
03900
04000 TOOHI: LDYI 177 ;Too high. Saturate positive.
04100 BNE INRNGE ;Jump.
04200
04300 NEGDAC: CPYI 200 ;Negative. Compare with -2↑7.
04700 SBCI 377
04800 BCS INRNGE
04900
05000 TOOLOW: LDYI 200 ;Too low. Saturate to -2↑7.
05100
05200 INRNGE: LDAY VETBL ;Straighting it.
05300 STA DAC ;Output 8 bits to the DAC.
05400 RTS
00100 ;Arithmetic routines.
00200 ;Enter with high byte in A, low in Y.
00300 ;Returns A = characteristic and sign, Y = mantissa.
00400 ;Clobbers X, LOGTMP, LOGTMP+1.
00500 LOG: STYZ LOGTMP ;Save the inputs.
00600 STAZ LOGTMP+1
00700
00800 LDXI 20+100 ;?Init characteristic to 15.
00900 CMPI 0 ;Test sign of input.
01000 BPL POSIN
01100 SEC ;Negative. 2's complement it.
01200 LDAI 0
01300 SBCZ LOGTMP
01400 STAZ LOGTMP
01500 LDAI 0
01600 SBCZ LOGTMP+1
01700 POSIN: BNE NORML ;Is high byte zero?
01800 LDAZ LOGTMP ;Yes. Low byte?
01900 BEQ RTRN ;If so, return zero.
02000 LDYI 0 ;Low nonzero. Shift left one
02100 STYZ LOGTMP ;byte,
02200 LDXI 10+100 ;change characteristic to 7.
02300 NORML: DEX ;Normalize the number, counting the
02400 ASLZ LOGTMP ;characteristic down. When the
02500 ROLA ;first "1" shifts out, we've subtracted
02600 BCC NORML ;1 from the normalized number
02700 ASLZ LOGTMP ;(This rounds the result)
02800 ADCI =11 ;and are left with the fraction
02900 TAY ;Adding 11 to that is equivalent to
03000 TXA ;adding 0.043.
03100 ADCI 0 ;Propagate the carry into the
03200 ;characteristic.
03300 ASLA ;Insert the sign bit from the saved
03400 ASLZ LOGTMP+1;input.
03500 RORA
03600 RTRN: RTS ;Done.
03700
03800 ;Enter with sign and characteristic in A, mantissa in Y
03900 ;Returns 16-bit integer, low byte in Y, high in A.
04000 ;Clobbers X, LOGTMP, LOGTMP+1.
04100 EXP: STAZ LOGTMP+1;Save sign of input.
04200 ANDI 177 ;Mask it off.
04300 BEQ ZEROIN ;Zero characteristic returns
04400 TAX ;zero.
04500 TYA ;Get the mantissa...
04600 SEC
04700 SBCI =11 ;...subtract 0.043...
04800 STAZ LOGTMP ;(save this value)
04900 TXA ;...propagate the carry and get rid
05000 SBCI 100 ;of the XS-64 offset.
05100 BMI NEGIN ;If negative (value < 1.0)
05200 ;return zero.
05300 CMPI =15 ;Test for overflow (value>=2↑15
05400 BCS SATUR
05500 TAX ;...no. Number is in range.
05600 ADCI 370 ;Is characteristic below 8?
05700 BMI BLOATE
05800 TAX ;No. Reduce if by 8,
05900 JSR UNNORM ;unnormalize.
06000 BMI GETTMP ;Jump.
00100 BLOATE: JSR UNNORM ;Yes. Unnormalize, then
00200 ASLZ LOGTMP ;(round result)
00300 ADCI 0
00400 STAZ LOGTMP ;use result as low byte and
00500 LDAI 0 ;set high byte to zero.
00600
00700 GETTMP: LDYZ LOGTMP
00800 GTMP1: LDXZ LOGTMP+1;Test sign of input...
00900 BPL POSIGN
01000 STAZ LOGTMP+1;...negative. 2's complement
01100 LDAI 0 ;the result.
01200 SEC
01300 SBCZ LOGTMP
01400 TAY
01500 LDAI 0
01600 SBCZ LOGTMP+1
01700 POSIGN: RTS
01800
01900 NEGIN: LDAI 0 ;Set the result to zero if the
02000 ZEROIN: TAY ;input is negative.
02100 RTS
02200
02300 SATUR: LDYI 377 ;Saturate result to 2↑15 - 1 if
02400 STYZ LOGTMP ;input was 15 or more.
02500 LDAI 177
02600 BNE GTMP1 ;Jump.
02700
02800 UNNORM: LDAI 1 ;Unnormalize subroutine. Add 1
02900 BNE DECRX ;to the fraction.
03000
03100 SCALE: ASLZ LOGTMP ;Scale the fraction left by the
03200 ROLA ;amount of the characteristic.
03300 DECRX: DEX
03400 BPL SCALE
03500 RTS
03600
03700 ;Enter with characteristic of multiplier in A,
03800 ;mantissa in Y, X pointing to a pair of base page
03900 ;locations containing the multiplicand (mantissa in the
04000 ;low byte).
04100 ;Returns the product in A and Y, same form as the
04200 ;multiplier. Leaves X unchanged. Clobbers LOGTMP and
04300 ;LOGTMP+1.
04400 MULTIP: PHA
04500 EORZX 1 ;Compute sign of result,
04600 STAZ LOGTMP+1 ;save it away.
04700 PLA
04800 ANDI 177 ;Mask off multiplier sign.
04900 BEQ ZEROIN ;If zero, return zero.
05000 STAZ LOGTMP
05100 TYA ;Add the two logarithms.
05200 CLC
05300 ADCZX 0
05400 TAY
05500 LDAZX 1
05600 ANDI 177 ;If multiplicand is zero,
05700 BEQ ZEROIN ;return a zero.
05800 ADCZ LOGTMP
05900 SEC
06000 SBCI 100 ;Correct the XS-64 offset.
00100 BPL INSIGN ;Result in range?
00200 ANDI 100 ;No. If underflow,
00300 BNE NEGIN ;return zero.
00400 LDAI 177 ;Overflow. Saturate to
00500 LDYI 377 ;highest magnitude.
00600
00700 INSIGN: ASLA ;Insert the sign of the result.
00800 ASLZ LOGTMP+1
00900 RORA
01000 RTS
01100
01200 ;Inverse function: 2's complement the magnitude part
01300 ;of a 15-bit logarithm.
01400 ;Enter with characteristic in A, mantissa in Y.
01500 ;Returns inverse in the same form. X unchanged.
01600 ;Clobbers LOGTMP and LOGTMP+1.
01700 INV: STYZ LOGTMP ;Pretty straightforward...
01800 STAZ LOGTMP+1
01900 SEC
02000 LDAI 0 ;Complement the number by
02100 SBCZ LOGTMP ;subtracting it from zero.
02200 TAY
02300 LDAI 0
02400 SBCZ LOGTMP+1
02500 JMP INSIGN ;Insert the original sign.
02600
02700 ;DAC output table.
02800 LOC (.∨377)+1 ;For start of next page.
02900 VETBL: ;DAC output table.
03000 N ← 0
03100 REPEATE 256,{N ↔ N←N+1 ↔}
03200
03300 NMI ← START ;Reset??
03400 ;Interrupt vectors.
03500 LOC 177772
03600 NMI∧377
03700 (NMI⊗-10)∧377
03800 START∧377
03900 (START⊗-10)∧377
04000 TICK∧377
04100 (TICK⊗-10)∧377
04200 END